package cn.teaseed.comn;

import cn.hutool.core.util.StrUtil;
import cn.hutool.cron.CronUtil;
import cn.hutool.cron.task.Task;
import cn.hutool.http.HttpRequest;
import cn.hutool.json.JSON;
import cn.hutool.json.JSONUtil;
import cn.teaseed.view.HomeView;
import com.illposed.osc.OSCBundle;
import com.illposed.osc.OSCMessage;
import com.illposed.osc.OSCPortOut;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.net.InetAddress;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Component
public class CronJobServer {

    private static final Map<Long, String> cronJobMap = new HashMap<>();

    private static final String cronStr = "0/{} * * * * ?";

    public void submitHttpJob(Long jobId) {
        JobEntity job = getJob(jobId);
        String pollTime = job == null ? "1" : job.getPollTime();
        //JOB轮询时间Cron表达式
        String cron = StrUtil.format(cronStr, pollTime);
        if (cronJobMap.get(jobId) == null || cronJobMap.get(jobId).isEmpty()) {
            //添加定时任务
            JobEntity taskJob = getJob(jobId);
            if (taskJob != null) {
                String schedule = scheduleTask(jobId, cron);
                cronJobMap.put(jobId, schedule);
            }
        } else {
            //移除定时任务重新添加
            String taskId = cronJobMap.get(jobId);
            //移除Task
            if (CronUtil.getScheduler().descheduleWithStatus(taskId)) {
                //移除成功
                JobEntity taskJob = getJob(jobId);
                if (taskJob != null) {
                    scheduleTask(jobId, cron);
                }
            } else {
                //移除失败
                log.error("任务ID：{}定时任务移除异常,未找到对应的TaskID", jobId);
            }
        }
    }

    private String scheduleTask(Long jobId, String cron) {
        return CronUtil.schedule(cron, (Task) () -> {
            JobEntity job = getJob(jobId);
            if (job != null) {
                String listener = job.getListener();

                String callback = job.getCallback();
                String callBackPort = job.getCallBackPort();

                //http请求
                String resp = null;
                try {
                    resp = HttpRequest.get(listener)
                            .timeout(1000)//超时毫秒
                            .execute().body();
                } catch (Exception e){
                    log.error("Http请求出现异常");
                    return;
                }
                resp = resp.replaceAll("\\n", "");

                //提取接口请求数据
                Boolean httpDataJp = job.getHttpDataJp();
                if (httpDataJp) {
                    JSON parse = JSONUtil.parse(resp);
                    resp = (String) parse.getByPath(job.getHttpDataJpText());
                }
                //格式化回调数据
                Map<String, Object> oscParam = new HashMap<>();
                Boolean httpDataFormat = job.getHttpDataFormat();
                if (httpDataFormat) {
                    String data = StrUtil.format(job.getHttpDataFormatText(), resp);
                    Object e = JSONUtil.parse(data);
                    oscParam.putAll((Map<String, String>) e);
                }

                try {
                    InetAddress ipAddress = InetAddress.getByName("127.0.0.1");
                    OSCPortOut out = new OSCPortOut(ipAddress, Integer.parseInt(callBackPort));
                    OSCMessage message = new OSCMessage();
                    message.setAddress(callback);
                    if (httpDataFormat) {
                        oscParam.forEach((k, v) -> {
                            message.addArgument(v);
                        });
                    } else {
                        message.addArgument(resp);
                    }
                    OSCBundle pack = new OSCBundle();
                    pack.addPacket(message);
                    out.send(pack);
                } catch (IOException e) {
                    log.error("HttpOSC发送异常,任务地址[{}]", job.getListener());
                }
            }
        });
    }

    private JobEntity getJob(Long jobId) {
        //获取JOB任务
        List<JobEntity> homeJobList = HomeView.localData.getHomeJobList();
        List<JobEntity> jobList = homeJobList.stream()
                .filter(entity -> entity.getId().equals(jobId)).collect(Collectors.toList());
        if (jobList.size() != 1) {
            log.error("Http任务ID异常");
            return null;
        }
        return jobList.get(0);
    }

    public void removeTask(Long jobId) {
        String taskId = cronJobMap.get(jobId);
        if (taskId == null || taskId.isEmpty()) return;
        boolean status = CronUtil.getScheduler().descheduleWithStatus(taskId);
        log.info("移除JOB:[{}],Task:[{}]-状态:[{}]", jobId, taskId, status);
    }

}
